package com.chhuang.utils.string;

import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.chhuang.utils.Assert;
import com.eaio.uuid.UUID;

/**
 * 字符串处理工具类
 * @author 程秀超
 * @date 2013-4-2
 *
 */
public class StringUtil {

	/** 需要过滤的字符集 */
	public static final String DEFAULT_FILTERED_CHAR = "`~\\:;\"'<,>./";
	
	/** 数据库中的需要处理的字符串集合 */
	public static final String[] DEFAULT_INVALID_STR = { "script", "and ", "or ", "union ", "between ", "\"", "\\", "\\t", "insert|values", "select|from", "update|set", "delete|from", "drop", "where", "alter" };
	
	/** 空字符串 */
	public static final String EMPTY_STR = "";
	
	/**
	 * 判断字符对象是否为空
	 * @param str
	 * @return
	 */
	public static boolean isEmpty(Object str) {
		return (str == null) || (String.valueOf(str).trim().length() < 1);
	}

	/**
	 * 判断字符对象非空
	 * @param str
	 * @return
	 */
	public static boolean isNotEmpty(Object str) {
		return !isEmpty(str);
	}

	/**
	 * 判断字符串是否为空
	 * @param str
	 * @return
	 */
	public static boolean isEmpty(String str) {
		return (str == null) || (str.trim().length() < 1);
	}

	/**
	 * 判断字符串非空
	 * @param str
	 * @return
	 */
	public static boolean isNotEmpty(String str) {
		return !isEmpty(str);
	}

	/**
	 * 判断字符串是否是浮点数格式
	 * @param str
	 * @return
	 */
	public static boolean isDecimal(String str) {
		boolean res = true;
		if (isEmpty(str))
			return false;
		try {
			new BigDecimal(str);
		} catch (NumberFormatException e) {
			res = false;
		}
		return res;
	}
	
	/**
	 * 判断字符串事发后是数字类型
	 * @param str
	 * @return
	 */
	public static boolean isNumeric(String str) {
		if (str == null || str.trim().length() == 0)
			return false;
		Pattern pattern = Pattern.compile("[0-9]*");
		Matcher isNum = pattern.matcher(str);
		if (!isNum.matches()) {
			return false;
		}
		return true;
	}

	/**
	 * 字符串转为整型
	 * @param str
	 * @return
	 */
	public static Integer string2Integer(String str) {
		if (isNotEmpty(str)) {
			try {
				return new Integer(str.trim());
			} catch (NumberFormatException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	/**
	 * 字符串转为整型，带默认值
	 * @param str
	 * @param defaultValue
	 * @return
	 */
	public static Integer string2Integer(String str, Integer defaultValue) {
		if (isNotEmpty(str)) {
			try {
				return new Integer(str.trim());
			} catch (NumberFormatException e) {
				e.printStackTrace();
				return defaultValue;
			}
		}
		return defaultValue;
	}

	/**
	 * 字符串转为长整型
	 * @param str
	 * @return
	 */
	public static Long string2Long(String str) {
		if (isNotEmpty(str)) {
			try {
				return new Long(str.trim());
			} catch (NumberFormatException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	/**
	 * 字符串转为长整型，带默认值
	 * @param str
	 * @param defaultValue
	 * @return
	 */
	public static Long string2Long(String str, Long defaultValue) {
		if (isNotEmpty(str)) {
			try {
				return new Long(str.trim());
			} catch (NumberFormatException e) {
				e.printStackTrace();
				return defaultValue;
			}
		}
		return defaultValue;
	}

	/**
	 * 字符串转为double类型
	 * @param str
	 * @return
	 */
	public static Double stringToDouble(String str) {
		if (isNotEmpty(str)) {
			try {
				return new Double(str.trim());
			} catch (NumberFormatException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	/**
	 * 字符串转为double类型，带默认值
	 * @param str
	 * @param defaultValue
	 * @return
	 */
	public static Double stringToDouble(String str, Double defaultValue) {
		if (isNotEmpty(str)) {
			try {
				return new Double(str.trim());
			} catch (NumberFormatException e) {
				e.printStackTrace();
				return defaultValue;
			}
		}
		return defaultValue;
	}

	/**
	 * 字符串转为BigDecimal类型
	 * @param str
	 * @return
	 */
	public static BigDecimal string2BigDecimal(String str) {
		if (isNotEmpty(str)) {
			try {
				return new BigDecimal(str);
			} catch (NumberFormatException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	/**
	 * 字符串转为BigDecimal类型，带默认值
	 * @param str
	 * @param defaultValue
	 * @return
	 */
	public static BigDecimal string2BigDecimal(String str,
			BigDecimal defaultValue) {
		if (isNotEmpty(str)) {
			try {
				return new BigDecimal(str);
			} catch (NumberFormatException e) {
				e.printStackTrace();
				return defaultValue;
			}
		}
		return defaultValue;
	}

	/**
	 * 数字格式化字符串
	 * @param value
	 * @return
	 */
	public static String numberFormat(String value) {
		if (!isEmpty(value)) {
			NumberFormat format = NumberFormat.getInstance();
			return format.format(Double.parseDouble(value));
		}
		return null;
	}

	/**
	 * 判断是否是中文字符
	 * @param c
	 * @return
	 */
	public static boolean isChinese(char c) {
		Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);

		return (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS)
				|| (ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS)
				|| (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A)
				|| (ub == Character.UnicodeBlock.GENERAL_PUNCTUATION)
				|| (ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION)
				|| (ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS);
	}

	/**
	 * 判断字符串是否包含中文字符
	 * @param str
	 * @return
	 */
	public static boolean isChinese(String str) {
		if (isEmpty(str)) {
			return false;
		}
		char[] ch = str.toCharArray();
		for (int i = 0; i < ch.length; i++) {
			char c = ch[i];
			if (isChinese(c) == true) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 判断两字符串是否相等
	 * @param str1
	 * @param str2
	 * @return
	 */
	public static boolean stringEquals(String str1, String str2) {
		if ((isEmpty(str1)) && (isEmpty(str2))) {
			return true;
		}

		if (isNotEmpty(str1)) {
			return str1.equals(str2);
		}

		return false;
	}

	/**
	 * 将字符串对象数组转为以逗号分隔字符串
	 * @param strArray
	 * @return
	 */
	public static String array2Str(Object[] strArray) {
		String str = "";
		for (int i = 0; i < strArray.length; i++) {
			str = str + strArray[i].toString() + ",";
		}
		if (str.length() > 0)
			str = str.substring(0, str.length() - 1);
		return str;
	}

	/**
	 * 判断邮件格式
	 * @param emailStr
	 * @return
	 */
	public static boolean checkEmail(String emailStr) {
		if (isEmpty(emailStr)) {
			return false;
		}
		return emailStr.matches("[-_.a-zA-Z0-9]+@[-_a-zA-Z0-9]+.[a-zA-Z]+");
	}

	/**
	 * 判断为字符串格式
	 * @param v
	 * @return
	 */
	public static boolean checkStr(String v) {
		if (isEmpty(v)) {
			return false;
		}
		return v.matches("[a-zA-Z0-9_]*");
	}

	/**
	 * 将以固定分隔符分隔的字符串转换为set
	 * @param commaString
	 * @param split
	 * @return
	 */
	public static Set<String> commaString2Set(String commaString, String split) {
		Set<String> s = new HashSet<String>();
		if (isNotEmpty(commaString)) {
			String[] arr = commaString.split(split);
			for (int i = 0; i < arr.length; i++) {
				s.add(arr[i].trim());
			}
		}
		return s;
	}

	/**
	 * 将以逗号分隔的字符串转换为set
	 * @param commaString
	 * @return
	 */
	public static Set<String> commaString2Set(String commaString) {
		return commaString2Set(commaString, ",");
	}

	/**
	 * 字符串是否包含目标子串
	 * @param str 字符串
	 * @param target 目标子串
	 * @param pos
	 * @param begin
	 * @param end
	 * @return
	 * @throws Exception
	 */
	public static boolean contains(String str, String target, int pos,
			char begin, char end) throws Exception {
		int b = str.indexOf(begin);
		int e = str.indexOf(end);
		if ((b < 0) || (e < 0)) {
			return false;
		}

		int len = target.length();
		System.out.println(str.length() + ":" + pos + ":" + len);
		String s = str.substring(pos, pos + len);
		if (!s.equalsIgnoreCase(target)) {
			throw new Exception("string['" + target + "]location:[" + pos
					+ "]Unspecified error");
		}

		String frontStr = str.substring(0, pos);
		String backStr = str.substring(pos + len + 1);

		int endCount = 0;
		int beginCount = 0;

		boolean existBegin = false;
		for (int i = 0; i < frontStr.length(); i++) {
			char c = frontStr.charAt(i);
			if (c == begin) {
				beginCount++;
			}
			if (c == end) {
				endCount++;
			}
		}
		if (beginCount - endCount > 0) {
			existBegin = true;
		}

		endCount = 0;
		beginCount = 0;

		boolean existEnd = false;
		for (int i = 0; i < backStr.length(); i++) {
			char c = backStr.charAt(i);
			if (c == begin) {
				beginCount++;
			}
			if (c == end) {
				endCount++;
			}
		}
		if (endCount - beginCount > 0) {
			existEnd = true;
		}
		return (existBegin) && (existEnd);
	}

	/**
	 * 过滤所有空格
	 * @param s
	 * @return
	 */
	public static String replaceAllBlank(String s) {
		if (isEmpty(s)) {
			return "";
		}
		return s.replaceAll("\\s", "");
	}

	/**
	 * 替换子串
	 * @param source 源字符串
	 * @param oldString 替换查找串
	 * @param newString 替换为的串
	 * @return
	 */
	public static String replaceAll(String source, String oldString,
			String newString) {
		if ((source == null) || (source.equals(""))) {
			return "";
		}
		StringBuffer output = new StringBuffer();

		int lengthOfSource = source.length();
		int lengthOfOld = oldString.length();

		int posStart = 0;
		int pos;
		while ((pos = source.indexOf(oldString, posStart)) >= 0) {
			output.append(source.substring(posStart, pos));

			output.append(newString);
			posStart = pos + lengthOfOld;
		}

		if (posStart < lengthOfSource) {
			output.append(source.substring(posStart));
		}

		return output.toString();
	}

	/**
	 * 将字符串数组转为逗号隔开字符串
	 * @param s
	 * @return
	 */
	public static String arr2CommaString(String[] s) {
		if ((s == null) || (s.length < 1)) {
			return "";
		}
		String result = s[0];
		if (s.length > 1) {
			for (int i = 1; i < s.length; i++) {
				result = result + "," + s[i];
			}
		}
		return result;
	}

	/**
	 * 将字符串列表转为逗号隔开字符串
	 * @param list
	 * @param splitStr
	 * @return
	 */
	public static String list2StringWithSplit(List<String> list, String splitStr) {
		if ((list == null) || (list.size() < 1)) {
			return null;
		}
		StringBuffer buf = new StringBuffer();
		Iterator<String> iter = list.iterator();
		while (iter.hasNext()) {
			buf.append(splitStr);
			buf.append(iter.next());
		}
		return buf.toString().substring(1);
	}

	/**
	 * 将列表转为带单引号，并以splitStr分隔的字符串
	 * @param list
	 * @param splitStr 分隔符
	 * @return
	 */
	public static String list2StringWithComma(Collection<String> list, String splitStr) {
		if ((list == null) || (list.size() < 1)) {
			return null;
		}
		StringBuffer buf = new StringBuffer();
		Iterator<String> iter = list.iterator();
		while (iter.hasNext()) {
			buf.append(splitStr);
			buf.append("'");
			buf.append(iter.next());
			buf.append("'");
		}

		return buf.toString().substring(1);
	}
	
	public static String minusStr(String totalStr, String minus) {
		return minusStr(totalStr, minus, ",");
	}
	
	/**
	 * 将字符串从可分割的母字符串删去
	 * @param totalStr
	 * @param minus
	 * @param splitter 默认逗号分隔
	 * @return
	 */
	public static String minusStr(String totalStr, String minus, String splitter) {
		if(Assert.isInvalidString(totalStr) || Assert.isInvalidString(minus)) {
			return totalStr;
		}
		
		if(Assert.isInvalidString(splitter)) {
			splitter = ",";
		}
		
		if(minus.indexOf(splitter) > -1) {
			System.err.println("待删减的字符串含有分隔符，不做处理，返回原字符串。");
			return totalStr;
		}
		
		String[] pers = totalStr.split(splitter);
		
		int len = pers.length;
		
		int index = -1;
		for(int i = 0; i < len; i++) {
			if(pers[i].equals(minus)) {
				index = i;
				break;
			}
		}
		
		if(index == -1) {
			return totalStr;
		}
		
		if(index != len - 1) {
			for(int i = index; i < len -1; i++) {
				pers[i] = pers[i+1];
			}
		}
		
		pers[len -1] = null;
		
		if(len == 1) {
			return "";
		}
		
		StringBuffer sb = new StringBuffer();
		
		for(int i = 0; i < len -1; i++) {
			sb.append(pers[i]);
			
			if(i != len -2) {
				sb.append(splitter);
			}
		}
		
		return sb.toString();
	}
	
	/**
	 * 生成uuid
	 * @return
	 */
    public static final synchronized String getUUID() {
        return new UUID().toString().replace("-", "");
    }
	
    public static void main(String args[]) {
    	String[] arr2CommaStringStrs = new String[]{"aa", "bb", "cc"};
    	String arr2CommaStringStr = arr2CommaString(arr2CommaStringStrs);
    	System.out.println("arr2CommaStringStr: " + arr2CommaStringStr);
    	
    	String[] array2StrStrs = new String[]{"aa", "bb", "cc"};
    	String array2StrStr = array2Str(array2StrStrs);
    	System.out.println("array2StrStr: " + array2StrStr);
    	
    	String email1 = "xcheng@synergyinfosys.net";
    	String email2 = "xcheng";
    	boolean checkEmail1 = checkEmail(email1);
    	boolean checkEmail2 = checkEmail(email2);
    	System.out.println("email1[" + email1 + "] is email? " + checkEmail1);
    	System.out.println("email2[" + email2 + "] is email? " + checkEmail2);
    	
    	String str1 = "abcde12345";
    	String str2 = "abcde*&12345";
    	boolean checkStr1 = checkStr(str1);
    	boolean checkStr2 = checkStr(str2);
    	System.out.println("checkStr1[" + str1 + "] is str? " + checkStr1);
    	System.out.println("checkStr2[" + str2 + "] is str? " + checkStr2);
    	
    	String commaString1 = "a,b,c,d,e;f";
    	Set<String> commaStrSet1 = commaString2Set(commaString1);
    	System.out.println("commaStr1[" + commaString1 + "] set size : " + commaStrSet1.size());
    
    	String commaString2 = "a;b;c;d;e;f";
    	Set<String> commaStrSet2 = commaString2Set(commaString2, ";");
    	System.out.println("commaStr2[" + commaString2 + "] set size : " + commaStrSet2.size());
    
    	String mstr = "aa,bb,cc";
    	String sstr = "dd,cc";
    	String rstr = minusStr(mstr, sstr);
    	System.out.println("minust str: " + rstr);
    }
    
}
